package gov.dhs.cis.soa.readers;

import gov.dhs.cis.soa.Constants;
import gov.dhs.cis.soa.SOAData;
import gov.dhs.cis.soa.Utils;
import gov.dhs.cis.soa.data.Actor;
import gov.dhs.cis.soa.data.EntitiesReferences;
import gov.dhs.cis.soa.data.Processes;
import gov.dhs.cis.soa.data.RelatedProperties;
import gov.dhs.cis.soa.data.UseCase;

import java.util.ArrayList;

import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;


public class ProcessLayerReader extends ExcelReader {
	static final Logger loger = Logger.getLogger(ProcessLayerReader.class);

	private final String PROC_FILE_NAME = "USCIS Architecture Components - Process Layer - Revised.xls";
	private String PROC_SHEET_NAME = "Implemented Processes";
	private String PROC_COL_NUM = "B";
	private String DESC_COL_NUM = "C";
	private String ST_COL_NUM = "E";
	private String WIPT_COL_NUM = "F";
	private String REL_COL_NUM = "G";
	private String MATURITY_COL_NUM = "H";
	private String IMPL_METHOD_COL_NUM = "J";
	private String STEPS_COL_NUM = "K";
	private String INTEG_COL_NUM = "O";
	private String DESIGN_COL_NUM = "P";
	private String USECASE_COL_NUM = "R";
	private String BUS_PROC_COL_NUM = "T";
	private String ACTOR_COL_NUM = "U";
	private String COMP_COL_NUM = "X";
	private String VOLUM_COL_NUM = "Y";

	private int MAX_PROCS = 86;
		
	public SOAData extractProcess(SOAData soaData) {
		loger.debug("Extracting Process/Actors layer Sheet...");
		HSSFWorkbook w = openFile(PROC_FILE_NAME);
		HSSFSheet s1 = w.getSheet(PROC_SHEET_NAME);
		int rows = s1.getLastRowNum();
		loger.debug("S1 rows =" + rows);
		
		ArrayList<Processes> procs = new ArrayList<Processes>();
		soaData.procList = procs;
		ArrayList<RelatedProperties> propsList = new ArrayList<RelatedProperties>();
		soaData.propsList = propsList;
		for (int n = 2; n < MAX_PROCS; n++) {
			HSSFRow row = s1.getRow(n);
			if(row == null)
				continue;
			String data = getCellStringValue(w, row, PROC_COL_NUM);
			if(Utils.isEmpty(data)) {
				loger.warn("Process Name is Null/Empty at row : " + n + ", ignoring this row.");
				continue;
			}
			String stereotype = getCellStringValue(w, row, ST_COL_NUM);
			if(Utils.isEmpty(stereotype)) {
				loger.warn("Process stereo type is Null/Empty at row : " + n + ", ignoring this row.");
				continue;
			}
			Processes proc = new Processes();
			proc.maturity = Utils.convert1stchar2Int(getCellStringValue(w, row, MATURITY_COL_NUM));
			if(proc.maturity == Constants.IOE_MATUR_REMOVE) {
				loger.warn("Process [" + proc.name + "] is marked for REMOVE at row : " + n + ", ignoring this row.");
				continue;
			}
			proc.id = Utils.getNextId();
			proc.name = getCellStringValue(w, row, PROC_COL_NUM);
			proc.stereotype = stereotype;
			proc.wipt = getCellStringValue(w, row, WIPT_COL_NUM);
			String compID = getCellStringValue(w, row, COMP_COL_NUM);
			proc.volumetrics = getCellIntegerValue(w, row, VOLUM_COL_NUM);
			proc.implMethod = getCellStringValue(w, row, IMPL_METHOD_COL_NUM);
			proc.steps = getCellStringValue(w, row, STEPS_COL_NUM);
			proc.integrationCfg = getCellStringValue(w, row, INTEG_COL_NUM);
			proc.designAspects = getCellStringValue(w, row, DESIGN_COL_NUM);
			proc.busProcName = getCellStringValue(w, row, BUS_PROC_COL_NUM);
			proc.descText = getCellStringValue(w, row, DESC_COL_NUM);
			
			String volumetrics = ""+proc.volumetrics;
			
			soaData.propsList.addAll(RelatedProperties.getNewProcessProperty(proc, "COMP_ID", compID));
			soaData.propsList.addAll(RelatedProperties.getNewProcessProperty(proc, "Volumetrics", volumetrics));
			
			proc.release = Utils.convert2Release(getCellStringValue(w, row, REL_COL_NUM));
			proc.createDescription();

			procs.add(proc);
			
			data = getCellStringValue(w, row, USECASE_COL_NUM);
			if(!Utils.isEmpty(data)) {
				data = data.replaceAll("\\n", ",");
				String[] usecases = data.split(",");
				if(usecases != null && usecases.length > 0) {
					for (String usecase : usecases) {
						usecase = usecase.trim();
						UseCase u = Utils.findUseCaseByNumber(usecase, soaData.useCaseList);
						if(u == null) {
							loger.error("Couldn't find UseCase for process: <" + proc.name + "> and UseCase:<" + usecase + ">");
							continue;
						}
						//proc.addReferedUseCase(u);
						soaData.addEntitiesReferences(EntitiesReferences.getNewEntitiesReference(proc, u, null));
					}
				}
			}
			data = getCellStringValue(w, row, ACTOR_COL_NUM);
			if(!Utils.isEmpty(data)) {
				data = data.replaceAll("\\n", ",");
				String[] acts = data.split(",");
				if(acts != null && acts.length > 0) {
					for (int i = 0; i < acts.length; i++) {
						String pActorName = acts[i].replaceAll("\\?", " ").trim();
						Actor a = Utils.findActorByName(pActorName, soaData.actorList);
						if(a == null) {
							loger.error("Couldn't find Actor for process: <" + proc.name + "> and Actor:<" + pActorName + ">");
							continue;
						}
						//proc.addReferedActor(a);
						soaData.addEntitiesReferences(EntitiesReferences.getNewEntitiesReference(proc, a, null));
					}
				}
			}
		}
		closeAll(w);
		return soaData;
	}
}
